import {
  BaseComponent, type IObject, definePage, udp, useUdpEffect, useRefCallback,
} from '@cscec/udp-ui';
import React from 'react';
import { DesignContext } from '@/components/editor/context';
import { getFieldPulgins, getTablePlugins, getPortalPlugins, getSystemCustomPlugins } from '@/components/editor/plugin';
import { setTableColumnFormat } from '@/components/editor/util';

export function encodeParams(params: IObject, keys = ['listInfo', 'editInfo', 'jsInfo', 'listUiContent', 'personalHomepageContent', 'editUiContent', 'scriptContent', 'workbenchContent', 'homepageContent']) {
  const copyParams = { ...params };
  keys.forEach((key) => {
    if (copyParams[key]) {
      copyParams[key] = udp.CryptoJS.encode(copyParams[key]);
    }
  });
  return copyParams;
}

// 门户
export function portalWrapper(Page: React.FC<any>, options: { isDesign: boolean }) {
  return definePage({
    // 页面加载前
    async injectProps() {
      return { plugins: getPortalPlugins(options.isDesign) };
    },
    initLoad: { script: false, language: false, ui: false },
    component: class extends BaseComponent {
      constructor(props: any) {
        super(props);
        this.state = {
          store: {
            session: 'design',
            loading: true,
            value: { type: 'container' },
            packages: undefined,
          },
          setStore: (newStore: any) => {
            this.setState((prevState: any) => ({ ...prevState, store: { ...prevState.store, ...newStore } }));
          },
        };
      }

      render() {
        return (
          <DesignContext.Provider value={this.state}>
            <Page {...this.props} page={this} />
          </DesignContext.Provider>
        );
      }
    },
  });
}

// 低码
export function lowcodeWrapper(Page: React.FC<any>, options: { tableService?: Function, isDesign: boolean, designType?: 'lowcode' | 'extension' }) {
  const { tableService, isDesign, designType } = options;
  return definePage({
    async injectProps() {
      const sysPlugins = getSystemCustomPlugins(isDesign, designType);
      if (isDesign) {
        const tables = await tableService?.();
        console.log('[debug] tables: ', tables);
        const fieldPlugins = getFieldPulgins(tables, designType);
        const tablePlugins = getTablePlugins(tables, designType);
        return { plugins: [...sysPlugins, ...fieldPlugins, ...tablePlugins], tables };
      }
      return { plugins: sysPlugins, tables: [] };
    },
    initLoad: { script: false, language: false, ui: false },
    component: class extends BaseComponent {
      designKey: string = 'list';

      constructor(props: any) {
        super(props);
        this.state = {
          store: {
            session: 'design',
            loading: true,
            packages: undefined,
            listInfo: { type: 'list-page' },
            editInfo: { type: 'detail-page' },
            jsInfo: '',
            recordVer: 1,
            schemeName: '',
            activeKey: 'list',
          },
          setStore: (newStore: any) => {
            this.setState((prevState: any) => ({ ...prevState, store: { ...prevState.store, ...newStore } }));
          },
        };
      }

      get busType() {
        return udp.getQueryValue('bizCode') || udp.getQueryValue('busType');
      }

      get Id() {
        return udp.getQueryValue('id');
      }

      render() {
        return (
          <DesignContext.Provider value={this.state}>
            <Page {...this.props} page={this} />
          </DesignContext.Provider>
        );
      }
    },
  });
}

// 重写amis编辑器的内置逻辑来适配qiankun
export function useAmisReWrite(amisRef: any) {
  useUdpEffect(() => {
    const dnd: any = amisRef.current?.manager.dnd;
    if (dnd) {
      dnd.createDragImage = (id: string, node: any) => {
        if (!dnd.dragImage) {
          const dragImage = document.createElement('div');
          dragImage.classList.add('ae-DragImage');
          dragImage.innerHTML = `<span>${node?.label || id}</span>`;
          const name = udp.external.getQianKun?.().name;
          const container = document.body.querySelector(`div[data-qiankun="${name}"]`) || document.body;
          container.appendChild(dragImage);
          dnd.dragImage = dragImage;
        }
        return dnd.dragImage;
      };
    }
    // 解决设计器区域选中无法取消的问题，直接禁止内部的区域选中，暂时不支持该功能
    const previewBody = amisRef.current?.mainRef.current?.querySelector('#editor-preview-body');
    const handle = e => {
      e.stopPropagation();
    };
    if (previewBody) {
      previewBody.addEventListener('mousedown', handle, true);
      return () => {
        previewBody?.removeEventListener('mousedown', handle, true);
      };
    }
  }, [amisRef.current]);
}

// 返回字段拖拽到编辑器的拦截器事件，控制组件拖拽位置逻辑
export function useDndEvent(amisRef: any, isList) {
  // const onBuildToolbars = useRefCallback((e)=>{
  //   e.context.info.removable = false
  // });

  const onDndAccept = useRefCallback((e) => {
    const targetSchema = amisRef.current?.store?.getNodeById(e.context.targetId)?.schema || {};
    if (e.data.table && targetSchema.table !== e.data.table) {
      return false;
    }
    return void 0;
  });

  const beforeInsert = useRefCallback((e) => {
    console.log('[debug] beforeInsert: ', e);
    const targetContext = e.context;
    const targetInfo = targetContext.info;
    const targetSchema = e.context.schema || {};
    const items = targetSchema.body || targetSchema.columns || [];
    // return void 0;

    //如果被拖动的是普通字段
    if(e.data.dragType === 'basic-field'){
      if(!['table','form'].includes(targetSchema.type)){
        udp.message('普通字段组件只能拖入表格中', 'warn');
        return false;
      }
    //如果是特定表格的字段
    }else if(e.data.dragType === 'specified-field' && e.data.table){  // 特定字段类型拖拽，有对应表格锁定
      if(!targetSchema.table || targetSchema.table !== e.data.table){  //目标容器可能是table或者form，这里只校验是指定tableId即可
        udp.message(`该字段组件只能拖入表格${e.data.table}中，不能放入当前容器内`, 'warn');
        return false;
      }
      if(e.data.name && items.some(c => c.name === e.data.name)){
        udp.message('该表格中已经存在该字段组件', 'warn');
        return false;
      }
    //如果被拖动的是特定表格
    }else if(['specified-table','specified-form'].includes(e.data.dragType)){ 
      //如果容器也是特定表格, 则不能嵌套。之前的aminsJson里没有定义dragType，这里只能通过type来判断
      if(['specified-table', 'specified-form'].includes(targetSchema.dragType) || targetSchema.type == 'form' || targetSchema.type == 'table'){ 
        udp.message('自定义表格组件不能嵌套自定义表格组件', 'warn');
        return false;
      }
      if(['list-page','detail-page'].includes(targetSchema.type)){
        if(targetContext.region === 'toolbar'){
          udp.message('自定义表格组件不能放入工具条区域', 'warn');
          return false;
        }else if(targetContext.region == 'tabs'){
          udp.message('明细区域请先添加tab选项卡，再拖入表格', 'warn');
          return false;
        }
      }
    //其他的，amis自带组件，容器etc
    }else{
      if(['specified-table', 'specified-form'].includes(targetSchema.dragType) || targetSchema.type == 'form' || targetSchema.type == 'table'){ 
        udp.message('自定义表格组件为限定容器，只能拖入指定字段', 'warn');
        return false;
      }
    }

    if(targetContext.region == 'tabs' && targetSchema.type == 'detail-page'){
      udp.message('明细区域请先添加tab选项卡，再添加内容', 'warn');
      return false;
    }

    // //如果目标容器是特定表格, 也需要反向过滤掉其他字段/组件/乱七八糟的组件，只能拖入指定字段。规避以上的else的部分内容，
    // if(['specified-table','specified-form'].includes(targetSchema.dragType) || 
    //   targetSchema.type == 'form' || targetSchema.type == 'table'){
    //   if(!(e.data.dragType == 'specified-field' && e.data.table == targetSchema.table)){
    //     udp.message(`自定义表格组件为限定容器，只能拖入指定字段`, 'warn');
    //     return false;
    //   }
    // }

    if (isList && targetSchema.type === 'table') {
      const { label, name, table, dataIndex, nameField,xtype } = e.data;
      const col = { label, name, table, dataIndex, nameField,xtype };
      setTableColumnFormat(col, e.data);
      Object.keys(e.data).forEach(k => {
        delete e.data[k];
      });
      Object.keys(col).forEach(k => {
        e.data[k] = col[k];
      });
    }
    return void 0;
  });

  const onActive = useRefCallback((e) => {
    console.log('[debug] onActive: ', e);
    // e.context.info.removable = false;
  })

  return { beforeInsert, onActive };
}
